package com.duobaoyu.dby.supply.biz.converter;

import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.config.PreWarningConfigTypeEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.order.OrderStatusEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.refund.AfterSaleStatusEnum;
import com.duobaoyu.dby.common.core.constant.CommonConstants;
import com.duobaoyu.dby.common.core.constant.StringPool;
import com.duobaoyu.dby.common.core.convert.bean.ReferenceMapper;
import com.duobaoyu.dby.common.mybatis.util.EnumUtils;
import com.duobaoyu.dby.supply.biz.enums.OrderRepairStatusEnum;
import com.duobaoyu.dby.supply.biz.exception.SupplyChainBizException;
import com.duobaoyu.dby.supply.common.biz.bo.config.PreWarningConfigGroupBO;
import com.duobaoyu.dby.supply.common.biz.dto.config.PreWarningConditionDTO;
import com.duobaoyu.dby.supply.db.entity.config.PreWarningConfig;
import com.duobaoyu.dby.supply.db.entity.order.OrderLogistics;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.mapstruct.Builder;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName PreWarningConfigConverter
 * @createTime 13:10:00 2023/10/16
 */
@Mapper(uses = {ReferenceMapper.class}, builder = @Builder(disableBuilder = true), componentModel = CommonConstants.COMPONENT_MODEL)
public interface PreWarningConfigConverter {

    @Mapping(target = "mobiles",expression = "java(mobileStrToList(preWarningConfig.getMobile()))")
    PreWarningConfigGroupBO.Item toPrePreWarningConfigGroupItem(PreWarningConfig preWarningConfig);

    default List<PreWarningConfigGroupBO.Item> toPrePreWarningConfigGroup(List<PreWarningConfig> preWarningConfigs, Map<Long,Long> countMap){
        if(CollectionUtils.isEmpty(preWarningConfigs)) {
            return Collections.emptyList();
        }
        ArrayList<PreWarningConfigGroupBO.Item> result = new ArrayList<>(preWarningConfigs.size());
        for (PreWarningConfig preWarningConfig : preWarningConfigs) {
            PreWarningConfigGroupBO.Item item = toPrePreWarningConfigGroupItem(preWarningConfig);
            long count = Objects.isNull(countMap) ? 0L : countMap.getOrDefault(item.getId(), 0L);
            item.setCount(count);
            result.add(item);
        }
        return result;
    }

    default List<String> mobileStrToList(String mobileStr){
        if(StrUtil.isEmpty(mobileStr)) {
            return Collections.emptyList();
        }
        return Arrays.asList(mobileStr.split(StringPool.COMMA));
    }

	default PreWarningConditionDTO parsePreWarningCondition(PreWarningConfig preWarningConfig) {
		if (Objects.isNull(preWarningConfig)) {
			return null;
		}
		PreWarningConfigTypeEnum preWarningConfigTypeEnum = EnumUtils.valueOf(PreWarningConfigTypeEnum.class, preWarningConfig.getType());
		if (Objects.isNull(preWarningConfigTypeEnum)) {
			return null;
		}
		PreWarningConditionDTO preWarningCondition = new PreWarningConditionDTO();
		switch (preWarningConfigTypeEnum) {
			case MANUAL_HANDLING:
				preWarningCondition.setStatus(Lists.newArrayList(OrderStatusEnum.MANUAL_HANDLING.getValue()));
				break;
			case LOGISTICS_EXCEPTION:
				preWarningCondition.setStatus(Lists.newArrayList(
						OrderStatusEnum.SHIPPED.getValue(),
						OrderStatusEnum.COMPLETE.getValue(),
						OrderStatusEnum.PART_SUCCESS.getValue()
				));
				String logisticsTableName = SqlHelper.table(OrderLogistics.class).getTableName();
				//实体字段名：表字段名
				Map<String, ColumnCache> logisticsColumnMap = LambdaUtils.getColumnMap(OrderLogistics.class);
				//实体属性名称
				String fieldName = LambdaUtil.getFieldName(OrderLogistics::getDeliveryOrderSn);
				//表字段名
				String deliveryOrderSnColumn = logisticsColumnMap.get(LambdaUtils.formatKey(fieldName)).getColumn();
				preWarningCondition.setNullFields(Lists.newArrayList(logisticsTableName.concat(StringPool.DOT).concat(deliveryOrderSnColumn)));
				preWarningCondition.setChannelCodes(Lists.newArrayList(ChannelCodeEnum.DE_LI.getValue()));
				break;
			case UNAUDITED_AFTER_SALES:
				preWarningCondition.setStatus(Lists.newArrayList(AfterSaleStatusEnum.TO_BE_REVIEWED_BY_CHANNEL.getValue()));
				break;
			case REVIEW_NOT_COMPLETED:
				preWarningCondition.setStatus(Lists.newArrayList(
						AfterSaleStatusEnum.CHANNEL_AUDIT_SUCCESS.getValue(),
						AfterSaleStatusEnum.TO_BE_SENT_BACK_BY_BUYER.getValue(),
						AfterSaleStatusEnum.PENDING_RECEIPT.getValue(),
						AfterSaleStatusEnum.TO_BE_CONFIRMED_BY_USER.getValue()
				));
				break;
			case DELIVERY_NOT_COMPLETED:
				preWarningCondition.setStatus(Lists.newArrayList(OrderStatusEnum.SHIPPED.getValue()));
				break;
			case ORDER_PAYMENT_NOT_SHIPPED:
				preWarningCondition.setStatus(Lists.newArrayList(OrderStatusEnum.WAIT_SHIP.getValue()));
				break;
			case WAIT_REPAIR_ORDER:
				preWarningCondition.setStatus(Lists.newArrayList(OrderRepairStatusEnum.WAIT_REPAIR.getValue(), OrderRepairStatusEnum.REPAIR_FAILED.getValue()));
				break;
			case WAIT_REJECT_CONFIRM:
				preWarningCondition.setStatus(Lists.newArrayList(AfterSaleStatusEnum.WAIT_REJECT_CONFIRM.getValue()));
				break;
			case WAIT_FILL_BACK_ADDRESS:
				preWarningCondition.setNeedSaleChannelAddress(Boolean.TRUE);
				break;
			default:
				SupplyChainBizException.fail("类型不存在");
		}
		// 处理时间参数
		if (Objects.nonNull(preWarningConfig.getLimitTimeNum()) && preWarningConfig.getLimitTimeNum() > 0 && Objects.nonNull(preWarningConfig.getUnit())) {
			TimeUnit unit = Objects.equals(preWarningConfig.getUnit(),CommonConstants.ONE) ? TimeUnit.DAYS : TimeUnit.HOURS;
			LocalDateTime limitDateTime = LocalDateTime.now().minusHours(unit.toHours(preWarningConfig.getLimitTimeNum()));
			preWarningCondition.setMaxDateTime(limitDateTime);
		}
		return preWarningCondition;
	}
}
